home *** CD-ROM | disk | FTP | other *** search
/ Belgian Amiga Club - ADF Collection / BS1 part 41.zip / BS1 part 41 / Compute`s Amiga resource 1.adf / Source / ALC / advgraph.c < prev    next >
C/C++ Source or Header  |  1989-02-07  |  32KB  |  1,053 lines

  1. /* Advanced Laser Chess graphics routines */
  2.  
  3. #include "advlaser.h"
  4. #include <hardware/blit.h>
  5. #include "advsound.h"
  6.  
  7. #define WAITTIME 3L     /* Used with Delay() */
  8.  
  9. /* External variables */
  10. extern int gate[4];              /* ADVLASER.C */
  11. extern ULONG grid[GRIDX][GRIDY]; /* ADVLASER.C */
  12. extern struct explosion_struct explode_info[MAXEXPLOSIONS]; /* ADVLASER.C */
  13. extern int turn;                 /* ADVLASER.C */
  14. extern int moves_left;           /* ADVLASER.C */
  15. extern unsigned long grid[15][11]; /* ADVLASER.C */
  16. extern int selected_x, selected_y; /* ADVLASER.C */
  17. extern BOOL select_flag;         /* ADVLASER.C */
  18. extern int background_on, background_period, background_channel; /* ADVSOUND.C */
  19. extern struct TextAttr font;     /* ADVLASER.C */
  20.  
  21. /* Local variables */
  22. struct BitMap *current_bitmap; /* Current bitmap to draw in */
  23. struct BitMap image_bitmap;   /* Image bitmap (contains piece images) */
  24. struct BitMap primary_bitmap; /* Primary screen */
  25. struct BitMap backup_bitmap;  /* Used for miscellaneous purposes */
  26. struct BitMap mask_bitmap;    /* Used for image masks */
  27. struct Screen *screen;
  28. struct NewScreen screen_def =
  29. {
  30.   0, 0, SCREENX, SCREENY, PLANES, /* Left, Top, width, height, depth */
  31.   0, 0,                 /* Detail/Block pens */
  32.   NULL,                 /* Display mode */
  33.   CUSTOMSCREEN | CUSTOMBITMAP, /* Screen type */
  34.   &font,                /* Font pointer */
  35.   NULL,                 /* Screen title */
  36.   NULL, NULL            /* No special gadgets; bitmap is set below */
  37. };
  38. struct Window *window;
  39. struct NewWindow window_def =
  40. {
  41.   0, 0, SCREENX, SCREENY, /* X, Y, width, height */
  42.   0, 1,                 /* Detail/block pen */
  43.   MOUSEBUTTONS | RAWKEY, /* IDCMP flags */
  44.   RMBTRAP | NOCAREREFRESH | SMART_REFRESH | ACTIVATE | BORDERLESS, /* Flags */
  45.   NULL,                 /* First gadget */
  46.   NULL,                 /* Check mark */
  47.   NULL,                 /* Title */
  48.   NULL,                 /* Screen - set later */
  49.   NULL,                 /* Bitmap */
  50.   0, 0, 0, 0,           /* Min & Max Width & Height */
  51.   CUSTOMSCREEN          /* Screen type */
  52. };
  53.  
  54.  
  55.  
  56. draw_grid()
  57. {
  58.   int x, y, d;
  59.  
  60.   draw_icons();
  61.   draw_border();
  62.   for(x=0;x<15;x++)
  63.     for(y=0;y<11;y++)
  64.     {
  65.       draw_square(x, y);
  66.       draw_piece(x, y, NORMAL);
  67.     }
  68.   if(select_flag)
  69.     highlight_square(selected_x, selected_y, NORMAL);
  70. }
  71.  
  72.  
  73.  
  74. draw_piece(x, y, flag)
  75. register int x, y, flag;
  76. {
  77.   int x_src, y_src; /* X and Y positions of piece in piece screen */
  78.   int i;
  79.  
  80.   /* Return if nothing at (x, y) or if it's a grid gate or hypersquare */
  81.   if(grid[x][y] == 0L || grid[x][y] == OTHER) return;
  82.  
  83.   /* Get coordinates of piece in piece screen, return if can't draw. */
  84.   if(!get_piece_coords(x, y, &x_src, &y_src)) return;
  85.  
  86.   /* Highlight the piece if stunned and if it isn't being drawn as hyperee. */
  87.   if(!(grid[x][y] & ALIVE) && !(flag & HYPEREE))
  88.   {
  89.     flag |= HIGHLIGHT;
  90.     flag &= ~NORMAL;
  91.   }
  92.  
  93.   /* Draw piece with optional shadow... */
  94.   if(flag & NORMAL)
  95.     draw_normal(x_src, y_src, x, y, flag & NOSHADOW? FALSE : TRUE);
  96.   else if(flag & HIGHLIGHT || flag & HYPEREE)
  97.     draw_special(x_src, y_src, x, y, flag, flag & NOSHADOW? FALSE : TRUE);
  98. }
  99.  
  100.  
  101.  
  102. /* Computes coordinates of piece in the image screen. */
  103. get_piece_coords(x, y, x_src, y_src)
  104. register int x, y, *x_src, *y_src;
  105. {
  106.   unsigned long id, obj;
  107.  
  108.   obj = grid[x][y];
  109.   id = grid[x][y] & 0x1FFFFFFE;    /* Mask off rotation and ALIVE bits */
  110.  
  111.   /* Mask off FIRED, HYPERED, and CRUNCHED bits on lasers, hypergons, kings,
  112.    * and crunching octagons */
  113.   if(id & (KILLLASER | STUNLASER | KING | HYPERGON | PARTOCTAGON | FULLOCTAGON))
  114.     id = id & ~FIRED;
  115.  
  116.   /* If I had the time, all of these numbers would be define statements
  117.    * for more flexible programming, but alas... */
  118.   switch(id)
  119.   {
  120.     case STUNLASER | RED:
  121.       *x_src = facing(obj) << 4;  *y_src = 1;  break;
  122.     case STUNLASER | GREEN:
  123.       *x_src = (facing(obj) << 4) + 128;  *y_src = 1;  break;
  124.     case BOMB | RED:
  125.       *x_src = 256;  *y_src = (int)facing(obj) * 18 + 1;  break;
  126.     case BOMB | GREEN:
  127.       *x_src = 272;  *y_src = (int)facing(obj) * 18 + 1;  break;
  128.     case FULLOCTAGON | RED:
  129.       *x_src = 288;  *y_src = 19;  break;
  130.     case FULLOCTAGON | GREEN:
  131.       *x_src = 288;  *y_src = 1;  break;
  132.     case PARTOCTAGON | RED:
  133.       *x_src = facing(obj) << 4;  *y_src = 19;  break;
  134.     case PARTOCTAGON | GREEN:
  135.       *x_src = (facing(obj) << 4) + 128;  *y_src = 19;  break;
  136.     case ONEWAYMIRROR | RED:
  137.       *x_src = facing(obj) << 4;  *y_src = 37;  break;
  138.     case ONEWAYMIRROR | GREEN:
  139.       *x_src = (facing(obj) << 4) + 128;  *y_src = 37;  break;
  140.     case TRIMIRROR | RED:
  141.       *x_src = facing(obj) << 4;  *y_src = 55;  break;
  142.     case TRIMIRROR | GREEN:
  143.       *x_src = (facing(obj) << 4) + 128;  *y_src = 55;  break;
  144.     case KILLLASER | RED:
  145.       *x_src = facing(obj) << 4;  *y_src = 73;  break;
  146.     case KILLLASER | GREEN:
  147.       *x_src = (facing(obj) << 4) + 128;  *y_src = 73;  break;
  148.     case SPLITTER | RED:
  149.       *x_src = facing(obj) << 4;  *y_src = 91;  break;
  150.     case SPLITTER | GREEN:
  151.       *x_src = (facing(obj) << 4) + 128;  *y_src = 91;  break;
  152.     case KING | RED:
  153.       *x_src = 256;  *y_src = 37;  break;
  154.     case KING | GREEN:
  155.       *x_src = 272;  *y_src = 37;  break;
  156.     case HYPERGON | RED:
  157.       *x_src = 256;  *y_src = 55;  break;
  158.     case HYPERGON | GREEN:
  159.       *x_src = 272;  *y_src = 55;  break;
  160.     default: return(FALSE);  break;  /* Can't draw any of the above */
  161.   }
  162.   return(TRUE);     /* Indicate acknowledgement */
  163. }
  164.  
  165.  
  166.  
  167. /* Draws a piece with optional shadow */
  168. draw_normal(x_src, y_src, x, y, shadow)
  169. register int x_src, y_src, x, y, shadow;
  170. {
  171.   int i;
  172.  
  173.   if(shadow)
  174.   {
  175.     draw_mask(x_src, y_src, x * GRIDSQUAREWIDTH + GRIDLEFT - 1,
  176.       y * GRIDSQUAREHEIGHT + GRIDTOP + 1,
  177.       GRIDSQUAREWIDTH, GRIDSQUAREHEIGHT, SHADOW);
  178.   }
  179.  
  180.   /* Copy piece's mask to currently displayed bitmap */
  181.   draw_mask(x_src, y_src, x * GRIDSQUAREWIDTH + GRIDLEFT,
  182.     y * GRIDSQUAREHEIGHT + GRIDTOP,
  183.     GRIDSQUAREWIDTH, GRIDSQUAREHEIGHT, NORMAL);
  184.  
  185.   /* Copy source image to destination bitmap */
  186.   BltBitMap(&image_bitmap, (long)x_src, (long)y_src, current_bitmap,
  187.     (long)(x * GRIDSQUAREWIDTH + GRIDLEFT), (long)(y * GRIDSQUAREHEIGHT +
  188.     GRIDTOP), (long)GRIDSQUAREWIDTH, (long)GRIDSQUAREHEIGHT,
  189.     ABNC|ANBC, -1L, NULL);
  190. }
  191.  
  192.  
  193.  
  194. /* Draws a highlighted piece or a hyperee, depending on flag. */
  195. draw_special(x_src, y_src, x, y, flag, shadow)
  196. register int x_src, y_src, x, y, flag, shadow;
  197. {
  198.   int i;
  199.  
  200.   if(shadow)
  201.   {
  202.     draw_mask(x_src, y_src, x * GRIDSQUAREWIDTH + GRIDLEFT - 1,
  203.       y * GRIDSQUAREHEIGHT + GRIDTOP + 1,
  204.       GRIDSQUAREWIDTH, GRIDSQUAREHEIGHT, SHADOW);
  205.   }
  206.  
  207.   draw_mask(x_src, y_src, x * GRIDSQUAREWIDTH + GRIDLEFT,
  208.     y * GRIDSQUAREHEIGHT + GRIDTOP,
  209.     GRIDSQUAREWIDTH, GRIDSQUAREHEIGHT, NORMAL);
  210.  
  211.   if(flag & HIGHLIGHT)  /* If piece is to be drawn highlighted... */
  212.   {
  213.     /* Draw as a white (highlight color) piece */
  214.     draw_mask(x_src, y_src, x * GRIDSQUAREWIDTH + GRIDLEFT,
  215.       y * GRIDSQUAREHEIGHT + GRIDTOP,
  216.       GRIDSQUAREWIDTH, GRIDSQUAREHEIGHT, HIGHLIGHT);
  217.   }
  218.   else if(flag & HYPEREE)
  219.   {
  220.     /* Draw piece in fade color */
  221.     draw_mask(x_src, y_src, x * GRIDSQUAREWIDTH + GRIDLEFT,
  222.       y * GRIDSQUAREHEIGHT + GRIDTOP,
  223.       GRIDSQUAREWIDTH, GRIDSQUAREHEIGHT, HYPEREE);
  224.   }
  225. }
  226.  
  227.  
  228.  
  229. /* type can be equal to SHADOW, HIGHLIGHT, NORMAL, or HYPEREE. */
  230. draw_mask(sx, sy, dx, dy, w, h, type)
  231. int sx, sy, dx, dy, w, h, type;
  232. {
  233.   register int mask, ih, ip, offset;
  234.   int ww, iw, i;
  235.  
  236.   ww = (w + 15) >> 4;  /* Word width */
  237.   /* Copy source image into mask bitmap */
  238.   BltBitMap(&image_bitmap, (long)sx, (long)sy, &mask_bitmap, 0L, 0L,
  239.     (long)w, (long)h, 0xC0L, -1L, NULL);
  240.  
  241.   /* For each word, or all bits in all planes for that word */
  242.   for(iw=0; iw < ww; iw++) /* Word width loop */
  243.     for(ih=0; ih < h; ih++)  /* Height */
  244.     {
  245.       mask = 0;
  246.       offset = (iw << 1) + (ih * ww << 1);
  247.       for(ip=0; ip < PLANES; ip++)  /* Number of planes */
  248.         mask |= *((UWORD *)(mask_bitmap.Planes[ip] + offset));
  249.       for(ip=0; ip < PLANES; ip++)
  250.         *((UWORD *)(mask_bitmap.Planes[ip] + offset)) = mask;
  251.     }
  252.  
  253.   /* "Punch a hole" through the playfield */
  254.   BltBitMap(&mask_bitmap, 0L, 0L, current_bitmap, (long)dx, (long)dy,
  255.     (long)w, (long)h, ANBC, -1L, NULL);
  256.  
  257.   if(type != NORMAL)
  258.   {
  259.     for(iw=0; iw < ww; iw++) /* Word width loop */
  260.       for(ih=0; ih < h; ih++)  /* Height */
  261.       {
  262.         offset = (iw << 1) + (ih * ww << 1);
  263.         if(type == SHADOW)
  264.           *((UWORD *)(mask_bitmap.Planes[0] + offset)) = 0;
  265.         else if(type == HIGHLIGHT)
  266.           for(i=1; i<PLANES; i++)
  267.             *((UWORD *)(mask_bitmap.Planes[i] + offset)) = 0;
  268.         else if(type == HYPEREE)
  269.         {
  270.           *((UWORD *)(mask_bitmap.Planes[0] + offset)) = 0;
  271.           *((UWORD *)(mask_bitmap.Planes[3] + offset)) = 0;
  272.         }
  273.       }
  274.  
  275.     BltBitMap(&mask_bitmap, 0L, 0L, current_bitmap, (long)dx, (long)dy,
  276.     (long)w, (long)h, ABNC|ANBC, -1L, NULL);
  277.   }
  278. }
  279.  
  280.  
  281.  
  282. animate_explosion(num_expl, explpx, explpy, explxv, explyv)
  283. int *explpx, *explpy, *explxv, *explyv;
  284. register int num_expl;
  285. {
  286.   int i, j, flash_index = 100, el, tx, ty, d;
  287.   int pix_save[EXPPTS];
  288.  
  289.   for(i=0; i<EXPPTS; i++)
  290.     pix_save[i] = ReadPixel(&screen->RastPort, (long)explpx[i], (long)explpy[i]);
  291.  
  292.   for(el=0; el<EXPLOSIONDISTANCE; el++) /* # of times to move points */
  293.   {
  294.     --flash_index;
  295.     for(i=0; i<EXPPTS; i++)
  296.     {
  297.       if(pix_save[i] != -1) /* If pixel is to be restored... */
  298.       {
  299.         SetAPen(&screen->RastPort, (long)pix_save[i]);
  300.         WritePixel(&screen->RastPort, (long)explpx[i], (long)explpy[i]);
  301.       }
  302.  
  303.       tx = explpx[i] + explxv[i];  /* Find next location of pixel */
  304.       ty = explpy[i] + explyv[i];
  305.  
  306.       /* If pixel is within grid boundary... */
  307.       if(tx > GRIDLEFT && tx < GRIDRIGHT && ty > GRIDTOP && ty < GRIDBOTTOM)
  308.       {
  309.         explpx[i] = tx;  /* Update coordinates of pixel */
  310.         explpy[i] = ty;
  311.       }
  312.       else  /* If pixel's next position is out of grid boundary... */
  313.       {
  314.         if(tx <= GRIDLEFT || tx >= GRIDRIGHT) /* If hit left or right edge... */
  315.           explxv[i] = -explxv[i];  /* Negate x velocity */
  316.         if(ty <= GRIDTOP || ty >= GRIDBOTTOM) /* If hit top or bottom... */
  317.           explyv[i] = -explyv[i];  /* Negate y velocity */
  318.       }
  319.       if(rnd(100) < flash_index)
  320.       {
  321.         /* Check value under new pixel location */
  322.         d = ReadPixel(&screen->RastPort, (long)explpx[i], (long)explpy[i]);
  323.         /* If the same color as another pixel, set flag to indicate not to draw next loop */
  324.         if(d == WHITE) pix_save[i] = -1;
  325.         else pix_save[i] = d;    /* Otherwise, restore with this color */
  326.         SetAPen(&screen->RastPort, WHITE); /* Plot new pixel */
  327.         WritePixel(&screen->RastPort, (long)explpx[i], (long)explpy[i]);
  328.       }
  329.       else pix_save[i] = -1;
  330.     }
  331.   }
  332.   for(i=0; i<EXPPTS; i++)
  333.     if(pix_save[i] != -1) /* If pixel is to be restored... */
  334.     {
  335.       SetAPen(&screen->RastPort, (long)pix_save[i]);
  336.       WritePixel(&screen->RastPort, (long)explpx[i], (long)explpy[i]);
  337.     }
  338. }
  339.  
  340.  
  341.  
  342. draw_border()
  343. {
  344.   struct RastPort *r;
  345.  
  346.   /* Could use DrawBorder() for this, but what the heck... */
  347.   r = &screen->RastPort;
  348.   SetAPen(r, GRID_BORDER_COLOR);
  349.   SetDrMd(r, JAM1);
  350.   Move(r, (long)(GRIDLEFT - 1), (long)(GRIDTOP - 1));
  351.   Draw(r, (long)(GRIDRIGHT + 1), (long)(GRIDTOP - 1));
  352.   Draw(r, (long)(GRIDRIGHT + 1), (long)(GRIDBOTTOM + 1));
  353.   Draw(r, (long)(GRIDLEFT - 1), (long)(GRIDBOTTOM + 1));
  354.   Draw(r, (long)(GRIDLEFT - 1), (long)(GRIDTOP - 1));
  355.   /* Draw border shadow */
  356.   SetAPen(r, BLACK);
  357.   Move(r, (long)(GRIDLEFT - 2), (long)(GRIDTOP + 2));
  358.   Draw(r, (long)(GRIDLEFT - 2), (long)(GRIDBOTTOM + 2));
  359.   Draw(r, (long)(GRIDRIGHT - 2), (long)(GRIDBOTTOM + 2));
  360. }
  361.  
  362.  
  363.  
  364. draw_square(x, y)
  365. int x, y;
  366. {
  367.   int index;
  368.  
  369.   if(x == GRIDX / 2 && y & 1) /* If drawing on grid gate or hypersquare... */
  370.     if(y & 1)
  371.     {
  372.       switch(y)
  373.       {
  374.         case 1: index = 0; break;
  375.         case 3: index = 1; break;
  376.         case 7: index = 2; break;
  377.         case 9: index = 3; break;
  378.         default: index = 0; break;  /* Dummy value; doesn't really matter */
  379.       }
  380.       if(gate[index] == CLOSED || y == GRIDY / 2)
  381.       { /* Draw empty square (with shadow) */
  382.         BltBitMap(&image_bitmap, (long)SP_EMPTYSQUAREX1,
  383.           (long)SP_EMPTYSQUAREY1, current_bitmap,
  384.           (long)(GRIDLEFT + (GRIDX / 2) * GRIDSQUAREWIDTH),
  385.           (long)(y * GRIDSQUAREHEIGHT + GRIDTOP),
  386.           (long)EMPTYSQUAREWIDTH, (long)EMPTYSQUAREHEIGHT,
  387.           BLIT_11_MINTERM, -1L, NULL);
  388.         return;
  389.       }
  390.     }
  391.  
  392.   SetAPen(&screen->RastPort, (long)square_color(x, y));
  393.   SetDrMd(&screen->RastPort, JAM1);
  394.   RectFill(&screen->RastPort, (long)(x * GRIDSQUAREWIDTH + GRIDLEFT),
  395.     (long)(y * GRIDSQUAREHEIGHT + GRIDTOP),
  396.     (long)(x * GRIDSQUAREWIDTH + GRIDLEFT + GRIDSQUAREWIDTH - 1),
  397.     (long)(y * GRIDSQUAREHEIGHT + GRIDTOP + GRIDSQUAREHEIGHT - 1));
  398. }
  399.  
  400.  
  401.  
  402. int square_color(x, y)  /* Returns the color value of a specified square */
  403. register int x, y;
  404. {
  405.   register int col;
  406.  
  407.   if(!(x & 1)) col = TRUE; /* Go through logic for correct color */
  408.   else col = FALSE;
  409.   if(y & 1) col = !col;
  410.   if(col) return(DARK_SQUARE);
  411.   else return(LIGHT_SQUARE);
  412. }
  413.  
  414.  
  415.  
  416. /* possible = NORMAL if the square is to be highlighted for a specific
  417.    piece, POSSIBLE if the square is to be highlighted as a possible
  418.    movement destination indicator. */
  419. highlight_square(gx, gy, possible)
  420. register int gx, gy, possible;
  421. {
  422.   int c;
  423.  
  424.   if(possible == NORMAL)
  425.     SetAPen(&screen->RastPort, HIGHLIGHT_COLOR);
  426.   else
  427.   {
  428.     set_color(DARK_POSSIBLE, COLOR_POSSIBLE_DARK);
  429.     c = square_color(gx, gy) == LIGHT_SQUARE? LIGHT_POSSIBLE : DARK_POSSIBLE;
  430.     SetAPen(&screen->RastPort, (long)c);
  431.   }
  432.  
  433.   RectFill(&screen->RastPort, (long)(gx * GRIDSQUAREWIDTH + GRIDLEFT),
  434.     (long)(gy * GRIDSQUAREHEIGHT + GRIDTOP),
  435.     (long)(gx * GRIDSQUAREWIDTH + GRIDLEFT + GRIDSQUAREWIDTH - 1),
  436.     (long)(gy * GRIDSQUAREHEIGHT + GRIDTOP + GRIDSQUAREHEIGHT - 1));
  437.   draw_piece(gx, gy, NORMAL);
  438. }
  439.  
  440.  
  441.  
  442. /* Animates square dropping from grid and takes care of piece existing
  443.  * on square (if any). */
  444. down_square(y)
  445. register int y;
  446. {
  447.   register int i, x_src = SP_GRIDGATEX1, y_src = SP_GRIDGATEY1;
  448.   int x_dest, y_dest;
  449.  
  450.   x_dest = GRIDLEFT + (GRIDX / 2) * GRIDSQUAREWIDTH;
  451.   y_dest = y * GRIDSQUAREHEIGHT + GRIDTOP;
  452.  
  453.   for(i=0; i<NUMSQUAREANIMS; i++)
  454.   {
  455.     BltBitMap(&image_bitmap, (long)x_src, (long)y_src, current_bitmap,
  456.       (long)x_dest, (long)y_dest, (long)GRIDGATEWIDTH,
  457.       (long)GRIDGATEHEIGHT, BLIT_11_MINTERM, -1L, NULL);
  458.  
  459.     /* Superimpose piece about to be destroyed (if any) */
  460.     draw_piece(7, y, HIGHLIGHT | NOSHADOW);
  461.  
  462.     Delay(WAITTIME);
  463.  
  464.     /* Move over to next "frame" of animation sequence */
  465.     x_src += GRIDGATESPACE;
  466.   }
  467.  
  468.   /* If there WAS a piece on that gate, it isn't there any longer. */
  469.   if(grid[GRIDX / 2][y])
  470.   {
  471.     BltBitMap(&image_bitmap, (long)SP_EMPTYSQUAREX1, (long)SP_EMPTYSQUAREY1,
  472.       current_bitmap, (long)x_dest, (long)y_dest, (long)EMPTYSQUAREWIDTH,
  473.       (long)EMPTYSQUAREHEIGHT, BLIT_11_MINTERM, -1L, NULL);
  474.     explode_info[0].flag = TRUE;
  475.     explode_info[0].x = GRIDX / 2;
  476.     explode_info[0].y = y;
  477.     explode();
  478.   }
  479.  
  480.   /* Mark this position as OTHER for the purpose of prohibiting movement */
  481.   grid[7][y] = OTHER;
  482. }
  483.  
  484.  
  485.  
  486. /* Animates a grid square coming up from nowhere */
  487. up_square(y)
  488. register int y;
  489. {
  490.   register int i;
  491.   register int x_src = SP_GRIDGATEX1 + GRIDGATESPACE * (NUMSQUAREANIMS - 1);
  492.   register int y_src = SP_GRIDGATEY1;
  493.   int x_dest, y_dest;
  494.  
  495.   x_dest = GRIDLEFT + (GRIDX / 2) * GRIDSQUAREWIDTH;
  496.   y_dest = y * GRIDSQUAREHEIGHT + GRIDTOP;
  497.  
  498.   for(i=0; i<NUMSQUAREANIMS; i++)
  499.   {
  500.     BltBitMap(&image_bitmap, (long)x_src, (long)y_src, current_bitmap,
  501.       (long)x_dest, (long)y_dest, (long)GRIDGATEWIDTH,
  502.       (long)GRIDGATEHEIGHT, BLIT_11_MINTERM, -1L, NULL);
  503.  
  504.     /* Superimpose piece about to be destroyed (if any) */
  505.     draw_piece(7, y, HIGHLIGHT | NOSHADOW);
  506.     Delay(WAITTIME);
  507.  
  508.     /* Move over to next "frame" of animation sequence */
  509.     x_src -= GRIDGATESPACE;
  510.   }
  511.  
  512.   grid[7][y] = 0L;  /* Erase any ID that was at this position before */
  513. }
  514.  
  515.  
  516.  
  517. down_hyper()   /* Animates hypersquare disappearing */
  518. {
  519.   register int i, x_src = SP_HYPERSQUAREX1, y_src = SP_HYPERSQUAREY1;
  520.   register int x_dest, y_dest;
  521.  
  522.   x_dest = GRIDLEFT + (GRIDX / 2) * GRIDSQUAREWIDTH;
  523.   y_dest = (GRIDY / 2) * GRIDSQUAREHEIGHT + GRIDTOP;
  524.  
  525.   for(i=0; i<NUMHYPERANIMS; i++)
  526.   {
  527.     BltBitMap(&image_bitmap, (long)x_src, (long)y_src, current_bitmap,
  528.       (long)x_dest, (long)y_dest, (long)HYPERSQUAREWIDTH,
  529.       (long)HYPERSQUAREHEIGHT, BLIT_11_MINTERM, -1L, NULL);
  530.     Delay(WAITTIME);
  531.  
  532.     /* Move over to next "frame" of animation sequence */
  533.     x_src += HYPERSQUARESPACE;
  534.   }
  535. }
  536.  
  537.  
  538.  
  539. up_hyper()   /* Animates hypersquare appearing from nowhere */
  540. {
  541.   register int i;
  542.   register int x_src = SP_HYPERSQUAREX1 + (NUMHYPERANIMS - 1) * HYPERSQUARESPACE;
  543.   register int y_src = SP_HYPERSQUAREY1;
  544.   register int x_dest, y_dest;
  545.  
  546.   x_dest = GRIDLEFT + (GRIDX / 2) * GRIDSQUAREWIDTH;
  547.   y_dest = (GRIDY / 2) * GRIDSQUAREHEIGHT + GRIDTOP;
  548.  
  549.   for(i=0; i<NUMHYPERANIMS; i++)
  550.   {
  551.     BltBitMap(&image_bitmap, (long)x_src, (long)y_src, current_bitmap,
  552.       (long)x_dest, (long)y_dest, (long)HYPERSQUAREWIDTH,
  553.       (long)HYPERSQUAREHEIGHT, BLIT_11_MINTERM, -1L, NULL);
  554.     Delay(WAITTIME);
  555.  
  556.     /* Move over to previous "frame" of animation sequence */
  557.     x_src -= HYPERSQUARESPACE;
  558.   }
  559. }
  560.  
  561.  
  562.  
  563. /* Fades out a piece drawn in the fade color and associates hyper sound with action */
  564. hyper_out(x, y)
  565. register int x, y;
  566. {
  567.   int rgb, drgb, i, j;
  568.  
  569.   /* Get RGB levels of square containing hyperee */
  570.   drgb = GetRGB4(screen->ViewPort.ColorMap, (long)square_color(x, y));
  571.   /* Get RGB levels of hyperee color */
  572.   hyperee_color(x, y);
  573.   rgb = GetRGB4(screen->ViewPort.ColorMap, FADE_COLOR);
  574.  
  575.   hyper_out_sound();
  576.   for(i=0; i<COLORSHADES; i++)
  577.   {
  578.     Delay(WAITTIME);
  579.     adjust_rgb(&rgb, drgb);
  580.     set_color(FADE_COLOR, rgb);
  581.   }
  582. }
  583.  
  584.  
  585.  
  586. hyper_in(x, y)      /* Fades in a piece and associates hyper sound */
  587. register int x, y;
  588. {
  589.   UWORD rgb, drgb, i;
  590.  
  591.   /* Get destination color (final fade color) of piece */
  592.   hyperee_color(x, y);
  593.   drgb = GetRGB4(screen->ViewPort.ColorMap, FADE_COLOR);
  594.   /* Get starting color of fading piece (same as the occupying square) */
  595.   rgb = GetRGB4(screen->ViewPort.ColorMap, (long)square_color(x, y));
  596.   set_color(FADE_COLOR, rgb);
  597.   draw_piece(x, y, HYPEREE); /* Draw piece in fade color WITH shadow */
  598.  
  599.   hyper_in_sound();
  600.   for(i=0; i<COLORSHADES; i++)
  601.   {
  602.     Delay(WAITTIME);
  603.     adjust_rgb(&rgb, drgb);
  604.     set_color(FADE_COLOR, rgb);
  605.   }
  606.   draw_piece(x, y, NORMAL);
  607. }
  608.  
  609.  
  610.  
  611. /* Sets FADE_COLOR depending on color of piece at (x, y) */
  612. hyperee_color(x, y)
  613. register int x, y;
  614. {
  615.   register UWORD rgb;
  616.  
  617.   if(grid[x][y] & RED)        /* If piece at (x, y) is red... */
  618.     rgb = GetRGB4(screen->ViewPort.ColorMap, BRIGHT_RED);
  619.   else if(grid[x][y] & GREEN) /* If piece is green... */
  620.     rgb = GetRGB4(screen->ViewPort.ColorMap, BRIGHT_GREEN);
  621.   if(!(grid[x][y] & ALIVE))   /* Otherwise, piece must be white (stunned) */
  622.     rgb = GetRGB4(screen->ViewPort.ColorMap, WHITE);
  623.   set_color(FADE_COLOR, rgb);
  624. }
  625.  
  626.  
  627.  
  628. adjust_rgb(rgb, drgb)  /* Moves RGB values towards that in drgb */
  629. UWORD *rgb, drgb;
  630. {
  631.   if(RED_VALUE(*rgb) < RED_VALUE(drgb))
  632.     *rgb += 0x0100;
  633.   else if(RED_VALUE(*rgb) > RED_VALUE(drgb))
  634.     *rgb -= 0x0100;
  635.  
  636.   if(GREEN_VALUE(*rgb) < GREEN_VALUE(drgb))
  637.     *rgb += 0x0010;
  638.   else if(GREEN_VALUE(*rgb) > GREEN_VALUE(drgb))
  639.     *rgb -= 0x0010;
  640.  
  641.   if(BLUE_VALUE(*rgb) < BLUE_VALUE(drgb))
  642.     *rgb += 0x0001;
  643.   else if(BLUE_VALUE(*rgb) > BLUE_VALUE(drgb))
  644.     *rgb -= 0x0001;
  645. }
  646.  
  647.  
  648.  
  649. fade()  /* Fades pointer color and icons to green or red */
  650. {
  651.   UWORD i, j, rgb[2], drgb[2];
  652.  
  653.   rgb[0] = GetRGB4(screen->ViewPort.ColorMap, POINTERHIGHLIGHT); /* Highlight */
  654.   rgb[1] = GetRGB4(screen->ViewPort.ColorMap, POINTERBODY); /* Body */
  655.  
  656.   if(turn == GREEN)
  657.   {
  658.     drgb[0] = GetRGB4(screen->ViewPort.ColorMap, BRIGHT_GREEN);
  659.     drgb[1] = GetRGB4(screen->ViewPort.ColorMap, GREEN_COLOR);
  660.   }
  661.   else
  662.   {
  663.     drgb[0] = GetRGB4(screen->ViewPort.ColorMap, BRIGHT_RED);
  664.     drgb[1] = GetRGB4(screen->ViewPort.ColorMap, RED_COLOR);
  665.   }
  666.   for(i=0; i<COLORSHADES; i++)
  667.   {
  668.     Delay(WAITTIME);
  669.     if(i & 1) modify_background_sound();
  670.     for(j=0; j<2; j++)
  671.     {
  672.       set_color(ICON_FADE_COLOR, rgb[1]);  /* Fade icons to normal colors */
  673.       set_color(POINTERHIGHLIGHT, rgb[0]);
  674.       set_color(POINTERBODY, rgb[1]);
  675.       adjust_rgb(&rgb[0], drgb[0]);
  676.       adjust_rgb(&rgb[1], drgb[1]);
  677.     }
  678.   }
  679. }
  680.  
  681.  
  682.  
  683. lower_shade(rgb)  /* Fades color in rgb towards black one shade */
  684. UWORD *rgb;
  685. {
  686.   if(RED_VALUE(*rgb) > 0)
  687.     *rgb -= 0x0100;
  688.   if(GREEN_VALUE(*rgb) > 0)
  689.     *rgb -= 0x0010;
  690.   if(BLUE_VALUE(*rgb) > 0)
  691.     *rgb -= 0x0010;
  692. }
  693.  
  694.  
  695.  
  696. /* Fades up all color registers to (TRUE) or from (FALSE) background color */
  697. fade_all(to_background, modify_snd)
  698. register int to_background, modify_snd;
  699. {
  700.   register int i, j;
  701.   UWORD rgb[SCREENCOLORS], drgb[SCREENCOLORS];
  702.   static UWORD rgbsave[SCREENCOLORS];
  703.   static BOOL first = TRUE;
  704.  
  705.   if(first)  /* Make a local copy of the colors */
  706.   {
  707.     first = FALSE;
  708.     for(i=0; i<SCREENCOLORS; i++)
  709.       rgbsave[i] = GetRGB4(screen->ViewPort.ColorMap, (long)i);
  710.   }
  711.  
  712.   for(i=0; i<SCREENCOLORS; i++)
  713.   {
  714.     drgb[i] = to_background? GetRGB4(screen->ViewPort.ColorMap, 0L) :
  715.       rgbsave[i];
  716.     rgb[i] = to_background? rgbsave[i] :
  717.       GetRGB4(screen->ViewPort.ColorMap, 0L);
  718.   }
  719.  
  720.   for(i=0; i<COLORSHADES; i++)
  721.   {
  722.     if(background_on && modify_snd) /* If background sound is playing... */
  723.       modify_sound(background_channel, background_period, to_background?
  724.        BACKGROUND_VOLUME - (i + 1) / BACKGROUND_VOLUME :
  725.        (i + 1) / BACKGROUND_VOLUME);
  726.     Delay(WAITTIME);
  727.     for(j=0; j<SCREENCOLORS; j++)
  728.     {
  729.       adjust_rgb(&rgb[j], drgb[j]);
  730.       set_color((long)j, rgb[j]);
  731.     }
  732.   }
  733. }
  734.  
  735.  
  736.  
  737. draw_moves(remaining)
  738. register int remaining;
  739. {
  740.   register int x;
  741.  
  742.   SetAPen(&screen->RastPort, 0L);  /* Background color */
  743.   RectFill(&screen->RastPort, (long)MOVESX1, (long)MOVESY1,
  744.     (long)(MOVESX1 + 1 + MOVEWIDTH * 3), (long)(MOVESY1 + MOVEHEIGHT));
  745.   if(remaining > 0)
  746.   {
  747.     x = remaining * MOVEWIDTH + (remaining - 1);
  748.     BltBitMap(&image_bitmap, (long)SP_MOVESX1, (long)SP_MOVESY1,
  749.       current_bitmap, (long)MOVESX1, (long)MOVESY1, (long)x,
  750.       (long)MOVEHEIGHT, BLIT_11_MINTERM, -1L, NULL);
  751.   }
  752. }
  753.  
  754.  
  755.  
  756. /* Handles the display portion of the end of a game.  The following
  757.   actions will be taken, depending on who gets blasted:
  758.   RED: grid squares and background color fade to shades of green.
  759.   GREEN: grid squares and background color fade to shades of red.
  760.   RED and GREEN: grid squares fade to alternating shades of green and
  761.     red (the normal dark squares turn to red, the light squares turn
  762.     to green), and the background color remains the same. */
  763. end_game_display(id)  /* The VICTIM's ID is passed to this routine. */
  764. unsigned long id;
  765. {
  766.   UWORD i, j, rgb[3], drgb[3];  /* [0]=dark square, [1]=light, [2]=background */
  767.   UWORD rgb_save[3];
  768.  
  769.   /* Get current color settings */
  770.   rgb[0] = rgb_save[0] = GetRGB4(screen->ViewPort.ColorMap, DARK_SQUARE);
  771.   rgb[1] = rgb_save[1] = GetRGB4(screen->ViewPort.ColorMap, LIGHT_SQUARE);
  772.   rgb[2] = rgb_save[2] = GetRGB4(screen->ViewPort.ColorMap, BACKGROUND);
  773.  
  774.   if((id & (GREEN | RED)) == GREEN) /* If green player loses... */
  775.   {
  776.     drgb[0] = GetRGB4(screen->ViewPort.ColorMap, RED_COLOR);
  777.     lower_shade(&drgb[0]);  /* Make new grid colors darker than pieces */
  778.     drgb[1] = drgb[0];
  779.     lower_shade(&drgb[1]);
  780.     drgb[2] = drgb[1];
  781.     lower_shade(&drgb[2]);
  782.   }
  783.   else if((id & (GREEN | RED)) == RED) /* If red player loses... */
  784.   {
  785.     drgb[0] = GetRGB4(screen->ViewPort.ColorMap, GREEN_COLOR);
  786.     lower_shade(&drgb[0]);  /* Make new grid colors darker than pieces */
  787.     drgb[1] = drgb[0];
  788.     lower_shade(&drgb[1]);
  789.     drgb[2] = drgb[1];
  790.     lower_shade(&drgb[2]);
  791.   }
  792.   else  /* A draw */
  793.   {
  794.     drgb[0] = GetRGB4(screen->ViewPort.ColorMap, RED_COLOR);
  795.     lower_shade(&drgb[0]);
  796.     drgb[1] = GetRGB4(screen->ViewPort.ColorMap, GREEN_COLOR);
  797.     lower_shade(&drgb[1]);
  798.     drgb[2] = GetRGB4(screen->ViewPort.ColorMap, BACKGROUND);
  799.   }
  800.  
  801.   victory_chord(TRUE);  /* Play victory chord */
  802.   for(i=0; i<COLORSHADES; i++)   /* Fade board to appropriate colors */
  803.   {
  804.     Delay(WAITTIME);
  805.     modify_victory_sound(1);
  806.     for(j=0; j<3; j++)
  807.       adjust_rgb(&rgb[j], drgb[j]);
  808.     set_color(DARK_SQUARE, rgb[0]);
  809.     set_color(LIGHT_SQUARE, rgb[1]);
  810.     set_color(BACKGROUND, rgb[2]);
  811.   }
  812.   dequeue_window();
  813.   release_mouse_buttons();  /* Wait for mouse button press */
  814.  
  815.   /* Fade back to normal colors */
  816.   for(j=0; j<3; j++)
  817.     drgb[j] = rgb_save[j];
  818.  
  819.   for(i=0; i<COLORSHADES; i++)
  820.   {
  821.     Delay(WAITTIME);
  822.     modify_victory_sound(-1);
  823.     for(j=0; j<3; j++)
  824.       adjust_rgb(&rgb[j], drgb[j]);
  825.     set_color(DARK_SQUARE, rgb[0]);
  826.     set_color(LIGHT_SQUARE, rgb[1]);
  827.     set_color(BACKGROUND, rgb[2]);
  828.   }
  829.  
  830.   victory_chord(FALSE);
  831. }
  832.  
  833.  
  834.  
  835. draw_back(x, y, highlight)    /* Draws piece on background screen */
  836. register int x, y, highlight;
  837. {
  838.   register struct BitMap *save;
  839.  
  840.   save = current_bitmap;
  841.   current_bitmap = &backup_bitmap;  /* Temporarily change pointers */
  842.   draw_piece(x, y, highlight);
  843.   current_bitmap = save;  /* Restore bitmap pointer */
  844. }
  845.  
  846.  
  847.  
  848. draw_beam_segment(x, y, lxd, lyd)  /* Draws a laser beam segment from center of grid square */
  849. int x, y, lxd, lyd;                /* (x, y) to (x + lxd, y + lyd). */
  850. {
  851.   int cf, tx, ty, out;
  852.   register int sx, sy, dx, dy;
  853.  
  854.   tx = x + lxd;  ty = y + lyd; /* Get destination point of laser beam */
  855.   /* If beam is going out of bounds... */
  856.   if(tx < 0 || tx >= GRIDX || ty < 0 || ty >= GRIDY)
  857.     out = TRUE;
  858.   else out = FALSE;
  859.  
  860.   if(lxd != 0 && lyd != 0) /* If beam is going at a diagonal... */
  861.   { /* Optimize the diagonal routine to draw from one grid square to next without having to change colors at mid-point (faster) */
  862.     sx = x * GRIDSQUAREWIDTH + GRIDLEFT + GRIDSQUAREWIDTH / 2;
  863.     sy = y * GRIDSQUAREHEIGHT + GRIDTOP + GRIDSQUAREHEIGHT / 2;
  864.     if(out)    /* If beam is going out of grid boundary... */
  865.     {
  866.       /* Set destination at half-way point so as not to draw out of
  867.        * grid boundary */
  868.       dx = sx + (1 + (GRIDSQUAREWIDTH / 2)) * lxd;
  869.       dy = sy + (1 + (GRIDSQUAREHEIGHT / 2)) * lyd;
  870.     }
  871.     else  /* If beam is within grid boundary... */
  872.     {
  873.       dx = tx * GRIDSQUAREWIDTH + (GRIDSQUAREWIDTH / 2) + GRIDLEFT;
  874.       dy = ty * GRIDSQUAREHEIGHT + (GRIDSQUAREHEIGHT / 2) + GRIDTOP;
  875.     }
  876.  
  877.     if(square_color(x, y) == DARK_SQUARE)
  878.       SetAPen(&screen->RastPort, LASER_DARK);
  879.     else SetAPen(&screen->RastPort, LASER_LIGHT);
  880.  
  881.     Move(&screen->RastPort, (long)(x * GRIDSQUAREWIDTH + GRIDLEFT +
  882.       GRIDSQUAREWIDTH / 2), (long)(y * GRIDSQUAREHEIGHT + GRIDTOP +
  883.       GRIDSQUAREHEIGHT / 2));
  884.     Draw(&screen->RastPort, (long)dx, (long)dy);
  885.     return;
  886.   }
  887.  
  888.   sx = x * GRIDSQUAREWIDTH + (GRIDSQUAREWIDTH / 2) + GRIDLEFT;
  889.   sy = y * GRIDSQUAREHEIGHT + (GRIDSQUAREHEIGHT / 2) + GRIDTOP;
  890.   /* Destination of half-way point */
  891.   dx = sx + (1 + (GRIDSQUAREWIDTH / 2)) * lxd;
  892.   dy = sy + (1 + (GRIDSQUAREHEIGHT / 2)) * lyd;
  893.  
  894.   cf = square_color(x, y) == DARK_SQUARE? TRUE : FALSE;
  895.   if(cf) SetAPen(&screen->RastPort, LASER_DARK);
  896.   else   SetAPen(&screen->RastPort, LASER_LIGHT);
  897.   Move(&screen->RastPort, (long)sx, (long)sy);
  898.   Draw(&screen->RastPort, (long)dx, (long)dy);
  899.   if(!out) /* If laser isn't going out of grid boundary... */
  900.   {
  901.     /* Make dest. of last segment the origin of this one (last half) */
  902.     sx = dx;  sy = dy;
  903.     dx = sx + (GRIDSQUAREWIDTH / 2) * lxd;
  904.     dy = sy + (GRIDSQUAREHEIGHT / 2) * lyd;
  905.     if(cf) SetAPen(&screen->RastPort, LASER_LIGHT);
  906.     else   SetAPen(&screen->RastPort, LASER_DARK);
  907.     Move(&screen->RastPort, (long)sx, (long)sy);
  908.     Draw(&screen->RastPort, (long)dx, (long)dy);
  909.   }
  910. }
  911.  
  912.  
  913.  
  914. /* Draws a box with a shadow with the given color register */
  915. draw_box(width, height, color_register)
  916. register int width, height;
  917. register long color_register;
  918. {
  919.   SetAPen(&screen->RastPort, color_register);
  920.   SetDrMd(&screen->RastPort, JAM1);
  921.   RectFill(&screen->RastPort, (long)(SCREENX / 2 - width / 2),
  922.    (long)(SCREENY / 2 - height / 2), (long)(SCREENX / 2 +
  923.    width / 2), (long)(SCREENY / 2 + height / 2));
  924.  
  925.   SetAPen(&screen->RastPort, BLACK);  /* Draw box shadow */
  926.   Move(&screen->RastPort, (long)(SCREENX / 2 - width / 2 - 1),
  927.    (long)(SCREENY / 2 - height / 2 + 1));
  928.   Draw(&screen->RastPort, (long)(SCREENX / 2 - width / 2 - 1),
  929.    (long)(SCREENY / 2 + height / 2 + 1));
  930.   Draw(&screen->RastPort, (long)(SCREENX / 2 + width / 2 -1),
  931.    (long)(SCREENY / 2 + height / 2 + 1));
  932. }
  933.  
  934.  
  935.  
  936. draw_icons()
  937. {
  938.   draw_closed_disk(FALSE);
  939.  
  940.   BltBitMap(&image_bitmap, (long)SP_QUITX1, (long)SP_QUITY1,
  941.     current_bitmap, (long)QUITX1, (long)QUITY1, (long)(QUITX2 - QUITX1),
  942.     (long)(QUITY2 - QUITY1), BLIT_11_MINTERM, -1L, NULL);
  943.  
  944.   BltBitMap(&image_bitmap, (long)SP_RESTARTX1, (long)SP_RESTARTY1,
  945.     current_bitmap, (long)RESTARTX1, (long)RESTARTY1,
  946.     (long)(RESTARTX2 - RESTARTX1), (long)(RESTARTY2 - RESTARTY1),
  947.     BLIT_11_MINTERM, -1L, NULL);
  948.  
  949.   BltBitMap(&image_bitmap, (long)SP_FIREX1, (long)SP_FIREY1,
  950.     current_bitmap, (long)FIREX1, (long)FIREY1, (long)(FIREX2 - FIREX1),
  951.     (long)(FIREY2 - FIREY1), BLIT_11_MINTERM, -1L, NULL);
  952.  
  953.   BltBitMap(&image_bitmap, (long)SP_PASSX1, (long)SP_PASSY1,
  954.     current_bitmap, (long)PASSX1, (long)PASSY1, (long)(PASSX2 - PASSX1),
  955.     (long)(PASSY2 - PASSY1), BLIT_11_MINTERM, -1L, NULL);
  956.  
  957.   BltBitMap(&image_bitmap, (long)SP_POSSIBLE_MOVESX1, (long)SP_POSSIBLE_MOVESY1,
  958.     current_bitmap, (long)POSSIBLE_MOVESX1, (long)POSSIBLE_MOVESY1,
  959.     (long)(POSSIBLE_MOVESX2 - POSSIBLE_MOVESX1),
  960.     (long)(POSSIBLE_MOVESY2 - POSSIBLE_MOVESY1), BLIT_11_MINTERM, -1L, NULL);
  961.  
  962.   BltBitMap(&image_bitmap, (long)SP_LOSSX1, (long)SP_LOSSY1,
  963.     current_bitmap, (long)LOSSX1, (long)LOSSY1, (long)(LOSSX2 - LOSSX1),
  964.     (long)(LOSSY2 - LOSSY1), BLIT_11_MINTERM, -1L, NULL);
  965. }
  966.  
  967.  
  968.  
  969. draw_closed_disk(audible) /* Draws a closed disk with optional sound */
  970. register int audible;
  971. {
  972.   if(audible) disk_close_sound();
  973.   BltBitMap(&image_bitmap, (long)SP_CLOSED_DISKX1, (long)SP_CLOSED_DISKY1,
  974.     current_bitmap, (long)DISKX1, (long)DISKY1, (long)(DISKX2 - DISKX1),
  975.     (long)(DISKY2 - DISKY1), BLIT_11_MINTERM, -1L, NULL);
  976. }
  977.  
  978.  
  979.  
  980. draw_open_disk()
  981. {
  982.   disk_open_sound();
  983.   BltBitMap(&image_bitmap, (long)SP_OPEN_DISKX1, (long)SP_OPEN_DISKY1,
  984.     current_bitmap, (long)DISKX1, (long)DISKY1, (long)(DISKX2 - DISKX1),
  985.     (long)(DISKY2 - DISKY1), BLIT_11_MINTERM, -1L, NULL);
  986. }
  987.  
  988.  
  989.  
  990. set_color(reg, color)
  991. register long reg;
  992. register UWORD color;
  993. {
  994.   SetRGB4(&screen->ViewPort, reg, RED_VALUE(color), GREEN_VALUE(color),
  995.     BLUE_VALUE(color));
  996. }
  997.  
  998.  
  999.  
  1000. clear_screen(bitmap) /* Clears PLANES number of planes in designated bitmap */
  1001. register struct BitMap *bitmap;
  1002. {
  1003.   register int i;
  1004.  
  1005.   for(i=0; i<PLANES; i++)
  1006.     BltClear(bitmap->Planes[i], (long)SCREENBYTES, 0L);
  1007. }
  1008.  
  1009.  
  1010.  
  1011. flip_screens()
  1012. {
  1013.   int class, code, qualifier, x, y;
  1014.  
  1015.   if(current_bitmap == &primary_bitmap)
  1016.     screen->ViewPort.RasInfo->BitMap = screen->RastPort.BitMap =
  1017.       current_bitmap = window->RPort->BitMap = &backup_bitmap;
  1018.   else
  1019.     screen->ViewPort.RasInfo->BitMap = screen->RastPort.BitMap =
  1020.       current_bitmap = window->RPort->BitMap = &primary_bitmap;
  1021. }
  1022.  
  1023.  
  1024.  
  1025. reset_view()  /* Makes sure currently-viewed bitmap is primary bitmap */
  1026. {
  1027.   current_bitmap = screen->ViewPort.RasInfo->BitMap =
  1028.     screen->RastPort.BitMap = window->RPort->BitMap = &primary_bitmap;
  1029.   MakeScreen(screen);
  1030.   RethinkDisplay();
  1031. }
  1032.  
  1033.  
  1034.  
  1035. copy_screen(source, destination) /* Copies a source bitmap to destination */
  1036. register struct BitMap *source, *destination;
  1037. {
  1038.   register int i;
  1039.  
  1040.   for(i=0; i<PLANES; i++)
  1041.     BltBitMap(source, 0L, 0L, destination, 0L, 0L,
  1042.     (long)SCREENX, (long)SCREENY, BLIT_11_MINTERM, -1L, NULL);
  1043. }
  1044.  
  1045.  
  1046.  
  1047. new_view()  /* Calls appropriate routines to display new view */
  1048. {
  1049.   MakeScreen(screen);
  1050.   RethinkDisplay();
  1051. }
  1052.  
  1053.